{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "_macros.html" as macros %}

{% block title %}语音识别模型基准测试系统{% endblock %}

{% block page_content %}
<div class="page-header">
    <a href="{{ url_for('.bt_task') }}">返回语音识别模型的基准测试用例总页</a>&nbsp;&nbsp;&nbsp;&nbsp;
    <a href="{{ url_for('.bttask_queue') }}">查看基准测试任务队列</a>&nbsp;&nbsp;&nbsp;&nbsp;
    <a href="{{ url_for('.btexec_history',bttask_id=bt_task.id) }}">查看该用例的任务执行记录</a>
    <p>用例名称: {{ bt_task.name }}</p>
    <p>测试场景：{% if bt_task.typ==0 %}训练场景{% elif bt_task.typ==1 %}推理场景{% endif %}</p>
    <p>计算设备：<span id="device-span">{{ bt_task.device_id }}</span></p>
    <p>备注：<span id="note_span">{{ bt_task.note }}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span id="add_note_button_span"><a href="javascript:void(0);" onclick="show_finish_add_note({{ bt_task.id }})"><button>添加备注</button></a></span><span id="show_finish_add_note_span"></span></p>
    <p>预期采集的基准测试指标类型：{{ metric_names }}</p>
    {% if test_project %}<p>测试项目：<a href="{{ url_for('.tp',id=test_project.id) }}">{{ test_project.name }}</a></p>{% endif %}
    <p>语音识别模型：{% if bt_task.model_id==-1 %}无{% else %}<a href="{{ url_for('.m',id=bt_task.model_id) }}">{{ model_name }}</a>{% endif %}</p>
    <p>语音的前端处理器（+语音的特征提取器）：{% if bt_task.fp_id==-1 %}无{% else %}<a href="{{ url_for('.ff',id=bt_task.fp_id) }}">{{ fp_name }}</a>{% endif %}</p>
    <p>语音的特征提取器：{% if bt_task.fe_id==-1 %}无{% else %}<a href="{{ url_for('.ff',id=bt_task.fe_id) }}">{{ fe_name }}</a>{% endif %}</p>
    {% if bt_task.typ==0 %}<p>训练数据集的数据预处理器：{% if bt_task.train_data_preprocessor_id==-1 %}无{% else %}<a href="{{ url_for('.dp',id=bt_task.train_data_preprocessor_id) }}">{{ train_data_preprocessor_name }}</a>{% endif %}</p>
    <p>验证数据集的数据预处理器：{% if bt_task.val_data_preprocessor_id==-1 %}无{% else %}<a href="{{ url_for('.dp',id=bt_task.val_data_preprocessor_id) }}">{{ val_data_preprocessor_name }}</a>{% endif %}</p>{% endif %}
    {% if bt_task.typ==1 %}<p>测试数据集的数据预处理器：{% if bt_task.test_data_preprocessor_id==-1 %}无{% else %}<a href="{{ url_for('.dp',id=bt_task.test_data_preprocessor_id) }}">{{ test_data_preprocessor_name }}</a>{% endif %}</p>{% endif %}
    <p>音频变换方式：{{ bt_task.audio_conversion }}</p>
    {% if bt_task.typ==0 %}<p>模型的保存目录：{{ bt_task.model_save_dir }}</p>
    <p>保存的模型内容类型：{% if bt_task.model_save_style==0 %}权重{% elif bt_task.model_save_style==1 %}权重+模型结构{% endif %}</p>
    <p>基准测试的结束指标类型：{% if bt_task.train_stop_criterion_category==0 %}损失变化量{% elif bt_task.train_stop_criterion_category==1 %}验证准确率{% elif bt_task.train_stop_criterion_category ==2 %}训练时间{% elif bt_task.train_stop_criterion_category==3 %}迭代数{% endif %}</p>
    <p>基准测试结束指标的阈值：{{ bt_task.train_stop_criterion_threshold }}</p>
    <p>基准测试结束条件的最少满足次数：{{ bt_task.train_stop_criterion_times }}</p>{% endif %}
    {% if bt_task.typ==1 %}<p>基准测试的结束指标类型：{% if bt_task.infer_stop_criterion_category==0 %}语音查询数量{% elif bt_task.infer_stop_criterion_category==1 %}推理时长{% endif %}</p>
    <p>基准测试结束指标的阈值：{{ bt_task.infer_stop_criterion_threshold }}</p>
    <p>推理场景的种类：{% if bt_task.infer_scenario_category==0 %}在线场景{% elif bt_task.infer_scenario_category==1 %}离线场景{% endif %}</p>
    {% if bt_task.infer_scenario_category==0 %}<p>在线推理场景下的客户端数量：{{ bt_task.infer_scenario_client_num }}</p>
    <p>在线推理场景下同一客户端所发送语音请求的时间间隔所服从的分布类型：{% if bt_task.infer_scenario_request_interval_distribution==0 %}均匀分布{% elif bt_task.infer_scenario_request_interval_distribution==1 %}正态分布{% elif bt_task.infer_scenario_request_interval_distribution==2 %}常量{% elif bt_task.infer_scenario_request_interval_distribution==3 %}0（持续请求）{% elif bt_task.infer_scenario_request_interval_distribution==4 %}语音时长{% endif %}</p>
    <p>在线推理场景下同一客户端所发送语音请求的时间间隔所服从的分布参数：{{ bt_task.infer_scenario_request_interval_distribution_params }}</p>{% endif %}{% endif %}
    <p>数据集：{% if bt_task.dataset_id ==-1 %}无{% else %}<a href="{{ url_for('.datasubsets',id=bt_task.dataset_id) }}">{{ dataset_name }}</a>{% endif %}</p>
    <p>是否重新汇总数据集中的语音文件及其转录文本：{% if bt_task.summary_again %}是{% else %}否{% endif %}</p>
    <p>是否保持所有语音数据在内存中：{% if bt_task.maintain_data_all %}是{% else %}否{% endif %}</p>
    <p>后处理器：{% if bt_task.post_processor_id==-1 %}无{% else %}<a href="{{ url_for('.pp',id=bt_task.post_processor_id) }}">{{ post_processor_name }}</a>{% endif %}</p>
    <p>批量大小：{{ bt_task.batch_size }}</p>
    {% if bt_task.typ==0 %}<p>每多少轮训练迭代后获取模型的训练状态：{{ bt_task.checkpoint_iters }}</p>
    <p>用于训练的语音文件数量：{{ bt_task.train_data_num }}</p>
    <p>用于验证的语音文件数量：{{ bt_task.val_data_num }}</p>
    <p>每获取多少次模型的训练状态后保存模型：{{ bt_task.save_ckpt_interval }}</p>{% endif %}
    {% if bt_task.typ==1 %}<p>用于测试的语音文件数量：{{ bt_task.test_data_num }}</p>{% endif %}
    <p>硬件开销指标数据的采集周期（以秒为单位）：{{ bt_task.hardware_cost_collection_interval }}</p>
    {% if able2update %}<a class="btn btn-default" href="{{ url_for('.bttask_edit',id=bt_task.id) }}">修改语音识别模型的基准测试用例信息</a>{% else %}<a class="btn btn-default" href="javascript:void(0);" title="任务状态为暂停中、已完成、被舍弃、执行出现错误和已提交时可修改" disabled>修改语音识别模型的基准测试用例信息</a>{% endif %}
    <a class="btn btn-default" href="{{ url_for('.bttask_delete',id=bt_task.id) }}">删除语音识别模型的基准测试用例信息</a><br>
    <a class="btn btn-default" href="{{ url_for('.bttask_json',id=bt_task.id) }}">导出语音识别模型的基准测试用例的json配置文件</a><br>
    <a class="btn btn-default" href="{{ url_for('.bttask_active',id=bt_task.id) }}">更新活动时间</a>
    <a class="btn btn-default" href="{{ url_for('.bttask_copy',id=bt_task.id) }}">以此为模版新建</a>
    <a class="btn btn-default" href="{{ url_for('.add_bttask_s_tp',bttask_id=bt_task.id) }}">将此测试用例添加到测试项目中</a><br>
    <a class="btn btn-default" href="javascript:void(0);" onclick="start_get_train_test_data_shape_type({{ bt_task.id }});">获取训练数据和测试数据的形状和类型</a><br>
    <h3>该用例分配到基准测试任务队列中的任务</h3>
    {% if btt_tasks|length==0 %}无<br>{% else %}
    {% for i in range(btt_tasks|length) %}
    任务<a href="{{ url_for('.btresults',btexec_id=btt_tasks[i][5]) }}">{{ btt_tasks[i][6] }}</a>编号<label>{{ btt_tasks[i][4] }}</label> 执行状态<label>{{ status_list[btt_tasks[i][1]] }}</label>  
    {% if btt_tasks[i][1] in [6] %}<a class="btn btn-default" href="{{ url_for('.set_bttask_status',id=btt_tasks[i][0],status=9,exec_id=btt_tasks[i][4],btexec_id=btt_tasks[i][5]) }}">暂停</a>{% else %}<a class="btn btn-default" href="javascript:void(0);" title="任务状态为执行中时可暂停" disabled>暂停</a>{% endif %}
                        {% if btt_tasks[i][1] in [3] %}<a class="btn btn-default" href="{{ url_for('.set_bttask_status',id=btt_tasks[i][0],status=1,exec_id=btt_tasks[i][4],btexec_id=btt_tasks[i][5]) }}">继续执行</a>{% else %}<a class="btn btn-default" href="javascript:void(0);" title="任务状态为暂停中时可继续执行" disabled>继续执行</a>{% endif %}
                        {% if btt_tasks[i][1] in [4,7] %}<a class="btn btn-default" href="{{ url_for('.set_bttask_status',id=btt_tasks[i][0],status=5,exec_id=btt_tasks[i][4],btexec_id=btt_tasks[i][5]) }}">舍弃</a>{% else %}<a class="btn btn-default" href="javascript:void(0);" title="任务状态为已完成和执行出现错误时可舍弃" disabled>舍弃</a>{% endif %}
                        {% if btt_tasks[i][1] in [1,3,6] %}<a class="btn btn-default" href="{{ url_for('.set_bttask_status',id=btt_tasks[i][0],status=10,exec_id=btt_tasks[i][4],btexec_id=btt_tasks[i][5],tip='用户手动取消任务的执行') }}">取消</a>{% else %}<a class="btn btn-default" href="javascript:void(0);" title="任务状态为待执行、暂停中和执行中时可取消" disabled>取消</a>{% endif %}
                        <a class="btn btn-default" href="{{ url_for('.delete_from_queue',task_idx=btt_tasks[i][-1],task_id=btt_tasks[i][0],status_id=btt_tasks[i][1],exec_id=btt_tasks[i][4]) }}">从队列中删除</a><br>
                        {% endfor %}{% endif %}
    <a class="btn btn-default" href="{{ url_for('.debug_bttask',bttask_id=bt_task.id) }}">调试本用例对应的基准测试任务</a>
    <a class="btn btn-default" href="{{ url_for('.set_bttask_status',id=bt_task.id,status=1,exec_id=-1,btexec_id=-1) }}">开始执行本用例对应的测试任务</a><br>
    <span id="span-1"></span><br>
    <span id="span-2"></span><br>
    <span id="span-3"></span>
</div>
<script type="text/javascript">

    function getCurStatus(bttask_id){
        $.getJSON('/exec/get_cur_status/'+bttask_id,function(data){
            console.log(data);
            $('#status_label').text(statuses[data['res']]);
        });
    }

    function show_finish_add_note(bttask_id){
        $('#add_note_button_span').html('');
        $('#show_finish_add_note_span').html('<input id="note_input" style="width:200px;" value="'+$('#note_span').text()+'"><a href="javascript:void(0)" onclick="add_note('+bttask_id+')"><button>完成</button></a>');
    }

    function add_note(bttask_id){
        $.ajax({
            type:'GET',
            url:'/add_bttask_note?note='+$('#note_input').val()+'&bttask_id='+bttask_id,
            success:function(data,status,request){
                $('#note_span').html($('#note_input').val());
            },
            error:function(){
                alert('请求添加基准测试用例的备注的过程中出现错误');
            }
        });
        $('#add_note_button_span').html('<a href="javascript:void(0)" onclick="show_finish_add_note('+bttask_id+')"><button>添加备注</button></a>');
        $('#show_finish_add_note_span').html('');
    }

    window.onload=function(){
        $.getJSON('/exec/detect_devices',function(data){
            let devices=data['devices'];
            let span_html='';
            for(let i=0;i<devices.length;i++){
                if(parseInt($('#device-span').text())==devices[i]['device_id']){
                    span_html+='id: '+devices[i]['device_id']+'&nbsp;&nbsp;&nbsp;&nbsp;'+devices[i]['name']+'&nbsp;&nbsp;&nbsp;&nbsp;最大频率'+devices[i]['freq']+'&nbsp;&nbsp;&nbsp;&nbsp;内存大小'+devices[i]['mem_size'];
                    break;
                }
            }
            $('#device-span').html(span_html);
        });
    }

    function update_status(url){
        $.getJSON(url,function(data){
            $('#span-1').text($('#span-2').text());
            $('#span-2').text($('#span-3').text());
            if('result' in data){
                $('#span-3').text(data['time']+' '+data['status']+' '+data['result']);
            }else{
                $('#span-3').text(data['time']+' '+data['state']+' '+data['status']);
            }
            if(data['state']=='PENDING'||data['state']=='PROGRESS'){
                setTimeout(function(){
                    update_status(url);
                },1000);
            }
        });
    }

    function start_get_train_test_data_shape_type(btt_id){
        $.ajax({
            type:'POST',
            url:'/get_train_test_data_shape_type/'+btt_id,
            success: function(data,status,request){
                status_url=request.getResponseHeader('Location');
                update_status(status_url);
            },
            error:function(){
                alert('获取训练数据和测试数据的形状和类型的过程中出现错误');
            }
        });
    }
</script>
{% endblock %}